/* ------------------------------------------------------------
 *  Bunny project - the interactive bunny space
 *
 * ------------------------------------------------------------ 
 */
import processing.opengl.*; 
import processing.serial.*;

// how much to scale the map by
final float	SCALE_FACTOR		= 1.3;
final float	TACTILE_SCALE_FACTOR	= 1.95;


// environment and simulator
BunnySpace environment = null;
Simulator sim = null;
DataStore fearMap = null;
FoodServer theFoodServer = null;
TacTileTracker tactile = null;

// used to calculate delta T between render loops
int lastMillis = 0;
float networkUpdateIn = 0.0;

void setup()
{
	
	// init control p5
	controlP5 = new ControlP5(this);
  
	if( isArduinoConnected )
	{
		println("Initializing serial connection...");
		println(Serial.list());
		port = new Serial(this, Serial.list()[0], 9600);
		//controlP5.addButton("Eating", 0, 10, 2, 30, 10);
		//controlP5.addButton("Ate", 1, 60, 2, 30, 10);
		//controlP5.addButton("Idle", 2, 110, 2, 30, 10);
	}
	
	// create environment
	fearMap = new DataStore();
	fearMap.loadFile(HEAT_MAP_FILE);
	fearMap.startServer(this);
	
        float theScale = isTacTileConnected ? TACTILE_SCALE_FACTOR : SCALE_FACTOR;
	environment = new BunnySpace( fearMap );
	environment.setScale( theScale );
	
        int w = round( theScale * (float) environment.getMapWidth() );
	int h = round( theScale * (float) environment.getMapHeight() );

	size(w, h);
	//smooth();


	// create simulator
	sim = new Simulator(
		environment.bunnyMap, 
		environment.obstacleMask, 
		BUNNY_COUNT, 
		FOOD_PATCH_COUNT
	);

        theFoodServer = new FoodServer(this);
        
        if ( isTacTileConnected )
        {
        		tactile = new TacTileTracker();
        		tactile.connect( this );
        }
        
}

void draw()
{
	/*
	      port.write('A');
	      port.write(0);
	*/
	
	// calculate delta time
	int m = millis();
	int dM = m - lastMillis;
	float dT = (float) dM / 1000.0;
	lastMillis = m;
	
	// clear
	background(0);
	
	pushMatrix();
	{	
		scale( environment.getScale(),  environment.getScale() );
			
		// render map
		environment.render( dT );
		
		// render simulation
		sim.render( dT );
	}
	popMatrix();
	
        theFoodServer.readFromNetwork();
        
	// update from network?
	networkUpdateIn -= dT;
	if (networkUpdateIn <= 0.0)
	{
		boolean update = fearMap.readFromNetwork();
                
		networkUpdateIn = NETWORK_UPDATE;
		
		if (update)
		{
			fearMap.saveFile(HEAT_MAP_FILE);
		}
		
		// read tactile touches
		if (tactile != null)
		{
			tactile.refresh();
		}
	}
	
	if (tactile != null)
	{
		tactile.draw();
	}	
}

void mouseClicked()
{
	environment.mouseClicked();
}

void keyPressed()
{
	if (key == 'g')
	{
		environment.toggleGrid();
	}
	else if (key == 'p' && environment.isGridVisible())
	{
		environment.toggleFoodPatchMode();
	}
	else if (key == ' ' && environment.isGridVisible())
	{
		sim.registerPatches( environment.getDishes() );
	}
}

PVector getMouse()
{
	float s = environment.getScale();
	return new PVector(
		(float) mouseX / s,
		(float) mouseY / s
	);
}

boolean inRect( PVector v, float xCorner, float yCorner, float w, float h)
{
	boolean in = v.x >= xCorner && v.x <= xCorner + w;
	in &= v.y >= yCorner && v.y <= yCorner + h;
	
	return in;
}

